import re
import datetime

from flask.ext.sqlalchemy import SQLAlchemy

from config import app


db = SQLAlchemy(app)

tags = db.Table('tags', db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
                db.Column('bookmark_id', db.Integer, db.ForeignKey('bookmark.id')))

tags_re = re.compile('\s*,\s*')


class Bookmark(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255), nullable=False)
    url = db.Column(db.String(255), nullable=False)
    created_at = db.Column(db.DateTime)
    updated_at = db.Column(db.DateTime)
    tags = db.relationship('Tag', secondary=tags, backref=db.backref('bookmarks', lazy='dynamic'))

    def save(self):
        tag_names = self.tag_names
        if tag_names:
            tags = Tag.query.filter(Tag.name.in_(tag_names)).all()
        else:
            tags = []

        new_tags = []
        for name in tag_names:
            found = False
            for tag in tags:
                if tag.name == name:
                    found = True
                    break
            if not found:
                new_tags.append(Tag(name=name))

        tags += new_tags
        self.tags = tags

        if self.id:
            self.updated_at = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        else:
            self.created_at = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            self.updated_at = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

    def set_tag_names(self, tag_names):
        if not isinstance(tag_names, (tuple, list)):
            tag_names = tags_re.split(tag_names)

        self._tag_names = tag_names

    def get_tag_names(self):
        if not hasattr(self, '_tag_names'):
            self._tag_names = [tag.name for tag in self.tags]
        return self._tag_names

    tag_names = property(get_tag_names, set_tag_names)

    @classmethod
    def url_exists(cls, url):
        return db.session.query(cls.query.filter_by(url=url).exists()).scalar()


class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, nullable=False)

    def save(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()
